package com.rankeiot.core.anno.interceptor;

import com.rankeiot.core.Current;
import com.rankeiot.core.anno.Auth;
import com.rankeiot.core.anno.OperationLog;
import com.rankeiot.core.data.UserInfo;
import com.rankeiot.core.event.LogEvent;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;


@RequiredArgsConstructor
public class OperationLogInterceptor implements HandlerInterceptor {
    final ApplicationContext context;
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                @Nullable Exception ex) throws Exception {
        if(!(handler instanceof HandlerMethod)){
            return;
        }
        HandlerMethod hm=(HandlerMethod) handler;
        OperationLog log = hm.getMethodAnnotation(OperationLog.class);
        if(log==null){
            return;
        }
        LogEvent logEvent = new LogEvent();
        logEvent.setLog(log);
        logEvent.setError(ex);
        logEvent.setIp(getIpAddr(request));
        logEvent.setPath(request.getRequestURI());
        logEvent.setQuery(request.getQueryString());

        UserInfo user = Current.user(log.needLogin());
        logEvent.setUserInfo(user);

        context.publishEvent(logEvent);
    }
    /**
     * 获取客户端IP
     *
     * @param request 请求对象
     * @return IP地址
     */
    public static String getIpAddr(HttpServletRequest request)
    {
        if (request == null)
        {
            return "unknown";
        }
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("X-Forwarded-For");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("X-Real-IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getRemoteAddr();
        }

        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
    }
    /**
     * 从多级反向代理中获得第一个非unknown IP地址
     *
     * @param ip 获得的IP地址
     * @return 第一个非unknown IP地址
     */
    public static String getMultistageReverseProxyIp(String ip)
    {
        // 多级反向代理检测
        if (ip != null && ip.indexOf(",") > 0)
        {
            final String[] ips = ip.trim().split(",");
            for (String subIp : ips)
            {
                if (false == isUnknown(subIp))
                {
                    ip = subIp;
                    break;
                }
            }
        }
        return ip;
    }

    /**
     * 检测给定字符串是否为未知，多用于检测HTTP请求相关
     *
     * @param checkString 被检测的字符串
     * @return 是否未知
     */
    public static boolean isUnknown(String checkString)
    {
        return !StringUtils.hasText(checkString) || "unknown".equalsIgnoreCase(checkString);
    }
}
